home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Softshoe / Lisa's Mac Parts / TextEdit / TextEditView.cp < prev    next >
Text File  |  2000-06-23  |  6KB  |  289 lines

  1. // TextEditView.cp
  2.  
  3. #ifndef TextEditView_h
  4. #include "TextEditView.h"
  5. #endif
  6. #ifndef MouseDownEvent_h
  7. #include "MouseDownEvent.h"
  8. #endif
  9. #ifndef CursorObject_h
  10. #include "CursorObject.h"
  11. #endif
  12. #ifndef Canvas_h
  13. #include "Canvas.h"
  14. #endif
  15. #ifndef ValidAndInvalidCanvasLoop_h
  16. #include "ValidAndInvalidCanvasLoop.h"
  17. #endif
  18. #ifndef FirstCanvas_h
  19. #include "FirstCanvas.h"
  20. #endif
  21.  
  22. TextEditView::TextEditView( GrafPortObject& port,
  23.                                      Focus& focus )
  24.   : Activator( focus ),
  25.      CommandHandler<Typing>( focus ),
  26.      CommandHandler<ReturnKeys>( focus ),
  27.      CommandHandler<HorizontalArrows>( focus ),
  28.      CommandHandler<VerticalArrows>( focus ),
  29.      CommandHandler<DeleteKeys>( focus ),
  30.      CommandHandler<Editing>( focus ),
  31.      CommandHandler<Selecting>( focus ),
  32.      editor( port, Rectangle( 0, 0, 530, 530 ), 530 ),
  33.      idle( *this, &TextEditView::Idle, 1000, false )
  34.   {
  35.     editor.ScrollAutomatically();
  36.   }
  37.  
  38. void TextEditView::AdjustToCanvas( const Canvas& canvas ) const
  39.   {
  40.     TextEditObject& mutableEditor = const_cast<TextEditObject&>( editor );
  41.     mutableEditor.DisplayAt( canvas.Port(),
  42.                                      canvas.OnScreen(),
  43.                                      canvas.OffScreen().TopLeft().AsPointObject() );
  44.   }
  45.  
  46. void TextEditView::Draw( const Canvas& canvas ) const
  47.   {
  48.     AdjustToCanvas( canvas );
  49.     
  50.     uint32 textHeight = (uint32)editor.LineCount() * editor.LineHeight();
  51.     uint32 scroll = editor.Scroll().v;
  52.     
  53.     if ( textHeight <= scroll )
  54.       {
  55.         EraseRect( &canvas.OnScreen() );
  56.         return;
  57.       }
  58.     
  59.     textHeight -= scroll;
  60.     
  61.     if ( textHeight < canvas.OnScreen().Height() )
  62.       {
  63.         Rectangle toErase( canvas.OnScreen() );
  64.         toErase.top += textHeight;
  65.         EraseRect( &toErase );
  66.       }
  67.  
  68.     editor.Draw( canvas.OnScreen() );
  69.   }
  70.  
  71. void TextEditView::Click( const Canvas& clicked,
  72.                                   const MouseDownEvent& event )
  73.   {
  74.     AdjustToCanvas( clicked );
  75.     editor.Click( event.LocalPoint(), event.Shift() );
  76.  
  77.     for ( ValidAndInvalidCanvasLoop canvas( *this );
  78.             canvas.Unfinished();
  79.             canvas++ )
  80.         if ( *canvas != clicked )
  81.             canvas->Invalidate();
  82.   }
  83.  
  84. const CursorObject& TextEditView::Cursor( const Canvas&,
  85.                                                         const MouseEvent&,
  86.                                                         RegionObject& ) const
  87.   {
  88.     return CursorObject::IBeam();
  89.   }
  90.  
  91. void TextEditView::Activate()
  92.   {
  93.     FirstCanvas canvas( *this );
  94.     AdjustToCanvas( *canvas );
  95.      
  96.     editor.Activate();
  97.     
  98.     idle.Enable();
  99.     idle.SetPeriod( editor.IdlePeriod() );
  100.   }
  101.  
  102. void TextEditView::Deactivate()
  103.   {
  104.     idle.Disable();
  105.  
  106.     FirstCanvas canvas( *this );
  107.     AdjustToCanvas( *canvas );
  108.  
  109.     editor.Deactivate();
  110.   }
  111.  
  112. void TextEditView::Idle()
  113.   {
  114.     if ( !editor.Selection().IsEmpty() )
  115.         return;
  116.     
  117.     FirstCanvas canvas( *this );
  118.     AdjustToCanvas( *canvas );
  119.     editor.Idle();
  120.   }
  121.  
  122. void TextEditView::Type( ConstData text )
  123.   {
  124.     FirstCanvas canvas( *this );
  125.     AdjustToCanvas( *canvas );
  126.     editor.ReplaceSelection( text );
  127.     editor.RevealSelection();
  128.   }
  129.  
  130. void TextEditView::ReturnKey( const KeystrokeEvent& )
  131.   {
  132.     FirstCanvas canvas( *this );
  133.     AdjustToCanvas( *canvas );
  134.     editor.TypeReturn();
  135.   }
  136.  
  137. void TextEditView::LeftArrow( const KeystrokeEvent& )
  138.   {
  139.     FirstCanvas canvas( *this );
  140.     AdjustToCanvas( *canvas );
  141.     editor.LeftArrow();
  142.   }
  143.  
  144. void TextEditView::RightArrow( const KeystrokeEvent& )
  145.   {
  146.     FirstCanvas canvas( *this );
  147.     AdjustToCanvas( *canvas );
  148.     editor.RightArrow();
  149.   }
  150.  
  151. void TextEditView::UpArrow( const KeystrokeEvent& )
  152.   {
  153.     FirstCanvas canvas( *this );
  154.     AdjustToCanvas( *canvas );
  155.     editor.UpArrow();
  156.   }
  157.  
  158. void TextEditView::DownArrow( const KeystrokeEvent& )
  159.   {
  160.     FirstCanvas canvas( *this );
  161.     AdjustToCanvas( *canvas );
  162.     editor.DownArrow();
  163.   }
  164.  
  165. void TextEditView::DeleteBackward( const KeystrokeEvent& )
  166.   {
  167.     FirstCanvas canvas( *this );
  168.     AdjustToCanvas( *canvas );
  169.     editor.DeleteBackward();
  170.   }
  171.  
  172. void TextEditView::DeleteForward( const KeystrokeEvent& )
  173.   {
  174.     FirstCanvas canvas( *this );
  175.     AdjustToCanvas( *canvas );
  176.     editor.DeleteForward();
  177.   }
  178.  
  179. bool TextEditView::CanCut()
  180.   {
  181.     return !editor.Selection().IsEmpty();
  182.   }
  183.  
  184. bool TextEditView::CanCopy()
  185.   {
  186.     return !editor.Selection().IsEmpty();
  187.   }
  188.  
  189. bool TextEditView::CanPaste()
  190.   {
  191.     return editor.CanPaste();
  192.   }
  193.  
  194. bool TextEditView::CanClear()
  195.   {
  196.     return !editor.Selection().IsEmpty();
  197.   }
  198.  
  199. void TextEditView::Cut()
  200.   {
  201.     FirstCanvas canvas( *this );
  202.     AdjustToCanvas( *canvas );
  203.     editor.Cut();
  204.   }
  205.  
  206. void TextEditView::Copy()
  207.   {
  208.     editor.Copy();
  209.   }
  210.  
  211. void TextEditView::Paste()
  212.   {
  213.     FirstCanvas canvas( *this );
  214.     AdjustToCanvas( *canvas );
  215.     editor.Paste();
  216.   }
  217.  
  218. void TextEditView::Clear()
  219.   {
  220.     FirstCanvas canvas( *this );
  221.     AdjustToCanvas( *canvas );
  222.     editor.DeleteSelection();
  223.   }
  224.  
  225. bool TextEditView::CanSelectAll() const
  226.   {
  227.     return editor.Selection() != editor.AllSelection();
  228.   }
  229.  
  230. void TextEditView::SelectAll()
  231.   {
  232.     FirstCanvas canvas( *this );
  233.     AdjustToCanvas( *canvas );
  234.     editor.SetSelection( editor.AllSelection() );
  235.   }
  236.  
  237. int32 TextEditView::BestWidth( Range32 bounds ) const
  238.   {
  239.     return bounds.WeaklyRestrict( 530 );
  240.   }
  241.  
  242. int32 TextEditView::BestHeight( Range32 bounds ) const
  243.   {
  244.     uint16 wrap = editor.WrapWidth();
  245.     
  246.     TextEditObject& mutableEditor = const_cast<TextEditObject&>( editor );
  247.     
  248.     mutableEditor.SetWrapWidth( 530 );
  249.     mutableEditor.Recalculate();
  250.     
  251.     int32 lineCount = editor.LineCount();
  252.     if ( lineCount == 0 )
  253.         lineCount = 1;
  254.     
  255.     int32 best = (lineCount + 2) * editor.LineHeight();
  256.     
  257.     mutableEditor.SetWrapWidth( wrap );
  258.     mutableEditor.Recalculate();
  259.  
  260.     if ( best < bounds.Start() )
  261.       {
  262.         best = bounds.Start() + editor.LineHeight() - 1;
  263.         best -= best % editor.LineHeight();
  264.         
  265.         if ( best <= bounds.End() )
  266.             return best;
  267.         
  268.         return bounds.Start();
  269.       }
  270.     
  271.     if ( best > bounds.End() )
  272.       {
  273.         best = bounds.End();
  274.         best -= best % editor.LineHeight();
  275.  
  276.         if ( best > 0 && best >= bounds.Start() )
  277.             return best;
  278.         
  279.         return bounds.End();
  280.       }
  281.     
  282.     return best;
  283.   }
  284.  
  285. int32 TextEditView::MinimumHeight() const
  286.   {
  287.     return editor.LineHeight();
  288.   }
  289.